#include "BuddyWnd.h"
#include "../Network/NetworkManager.h"
#include "../Network/Connection.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include "../Network/Messages/PeerViewInfoMsg.h"
#include "../Network/ChatWnd.h"
#include <QMenu>
#include "../Settings/GameSettings.h"
#include "../Network/Messages/MsgSystem.h"

BuddyWnd::BuddyWnd(QWidget *parent) :
    QWidget(parent)
{    
    QVBoxLayout *pLayout = new QVBoxLayout();
    mpTree = new QTreeWidget();
    mpTree->setContextMenuPolicy(Qt::CustomContextMenu);
    mpTree->setColumnCount(1);
    mpTree->setUniformRowHeights(true);
    mpTree->setHeaderLabel("Buddies");
    mpTree->setRootIsDecorated(false);
    mpTree->setIndentation(30);
    mpTree->setUniformRowHeights(true); 
    mpTree->setStyleSheet("background-color: #F1F1F1");
    pLayout->addWidget(mpTree);
    this->setLayout(pLayout);
    mpChatWnd = new ChatWnd(GameSettings::me()->mostTopWnd());

    connect(mpTree,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),SLOT(buddyDoubleClicked(QTreeWidgetItem*,int)));
    connect(mpTree,SIGNAL(customContextMenuRequested(QPoint)),SLOT(customContextMenutRequestedFromBuddyTree(QPoint)));
    connect(mpChatWnd,SIGNAL(askForPlaying(Connection*)),this,SIGNAL(askForPlaying(Connection*)));

    this->resize(200,400);
}

void BuddyWnd::setNetManager(NetworkManager *pNetManager)
{
    mpNetManager = pNetManager;
    connect(mpNetManager,SIGNAL(newParticipant(Connection*)),SLOT(peerJoined(Connection*)));
    connect(mpNetManager,SIGNAL(participantLeft(Connection*)),SLOT(peerLeft(Connection*)));
    connect(mpNetManager,SIGNAL(chatMsgCame(Connection*,ChatMsg*)),SLOT(chatMsgCame(Connection*,ChatMsg*)));
}

NetworkManager *BuddyWnd::netManager()
{
    return mpNetManager;
}

void BuddyWnd::buddyDoubleClicked(QTreeWidgetItem *pItem, int nColumn)
{
    Connection *pConn = mMapConnItem.key(pItem);

    if(pConn){
        mpChatWnd->show();
        mpChatWnd->addOrFindTab(pConn);
    }
}

void BuddyWnd::peerJoined(Connection *pConn)
{
    if(!mMapConnItem.contains(pConn)){
        QTreeWidgetItem *pItem = new QTreeWidgetItem();
        pItem->setFont(0,QFont("Helvetica [Cronyx]",14,QFont::Bold));
        mMapConnItem[pConn] = pItem;
        mpTree->addTopLevelItem(pItem);
        connect(pConn,SIGNAL(peerViewInfoChanged()),this,SLOT(peerViewInfoChanged()));
        connect(pConn,SIGNAL(peerViewInfoChanged()),mpChatWnd,SLOT(peerViewInfoChanged()));
        connect(pConn,SIGNAL(statusChanged(Connection*)),this,SLOT(peerStatusChanged(Connection*)));        
    }
}

void BuddyWnd::peerLeft(Connection *pConn)
{
    if(mMapConnItem.contains(pConn)){
        QTreeWidgetItem *pItem = mMapConnItem[pConn];
        int nInd = mpTree->indexOfTopLevelItem(pItem);
        mMapConnItem.remove(pConn);
        mpChatWnd->closeTab(pConn);

        if(nInd >=0){
            mpTree->takeTopLevelItem(nInd);
        }

        delete pItem;
        disconnect(pConn,SIGNAL(peerViewInfoChanged()),this,SLOT(peerViewInfoChanged()));
        disconnect(pConn,SIGNAL(peerViewInfoChanged()),mpChatWnd,SLOT(peerViewInfoChanged()));
        disconnect(pConn,SIGNAL(statusChanged(Connection*)),this,SLOT(peerStatusChanged(Connection*)));
    }
}

void BuddyWnd::chatMsgCame(Connection *pFrom, ChatMsg *pMsg)
{
    mpChatWnd->show();
    mpChatWnd->newMsg(pFrom,pMsg);
}

void BuddyWnd::peerViewInfoChanged()
{
    Connection *pConn = reinterpret_cast<Connection*>(sender());

    if(pConn && mMapConnItem.contains(pConn)){
        QTreeWidgetItem *pItem = mMapConnItem[pConn];
        setPeerText(pConn);
        pItem->setBackgroundColor(0,pConn->peerViewInfo()->color());

    }
}

void BuddyWnd::customContextMenutRequestedFromBuddyTree(QPoint ptLocation)
{
    QTreeWidgetItem *pItem = mpTree->itemAt(ptLocation);

    if(pItem){
        Connection *pPeer = mMapConnItem.key(pItem);

        if(pPeer){
            QMenu *pMenu = new QMenu();
            QAction *pActChat = pMenu->addAction(QString("Chat with ") + pPeer->peerViewInfo()->name());
            QAction *pActAskPlay = pMenu->addAction(QString("Ask for playing with ") + pPeer->peerViewInfo()->name());
            pMenu->setDefaultAction(pActChat);
            QAction *pActResult = pMenu->exec(mpTree->mapToGlobal(ptLocation));

            if(pActChat == pActResult){
                mpChatWnd->addOrFindTab(pPeer);
                mpChatWnd->show();
            }
            else if(pActAskPlay == pActResult){
                emit askForPlaying(pPeer);
            }
        }
    }
}

void BuddyWnd::peerStatusChanged(Connection *pConn)
{
    setPeerText(pConn);
}

void BuddyWnd::setPeerText(Connection *pConn)
{
    if(mMapConnItem.contains(pConn)){
        QTreeWidgetItem *pItem = mMapConnItem[pConn];

        if(pItem){
            QString strInfo = ServerInfoMsg::Free == pConn->status() ? "" : tr(" (") +
                              MsgSystem::readableStatus(pConn->status()) + tr(")");
            pItem->setText(0,pConn->peerViewInfo()->name() + strInfo);
        }
    }
}
